/**
 * Copyright (c) 2021 Coder League
 * All rights reserved.
 *
 * File：OrderService.java
 * History:
 *         2021年1月27日: Initially created, Chrise.
 */
package club.coderleague.cfss.service.order;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import club.coderleague.cfss.config.properties.FileUploadSettings;
import club.coderleague.cfss.dao.GoodDao;
import club.coderleague.cfss.dao.OrderDao;
import club.coderleague.cfss.dao.OrderGoodDao;
import club.coderleague.cfss.dao.OrderLogDao;
import club.coderleague.cfss.domain.beans.Order;
import club.coderleague.cfss.domain.beans.OrderGoodCheck;
import club.coderleague.cfss.domain.beans.OrderGoodRequest;
import club.coderleague.cfss.domain.beans.SubmitOrderRequest;
import club.coderleague.cfss.domain.beans.UserSession;
import club.coderleague.cfss.domain.entities.Ordergoods;
import club.coderleague.cfss.domain.entities.Orderlogs;
import club.coderleague.cfss.domain.entities.Orders;
import club.coderleague.cfss.domain.enums.EntityState;
import club.coderleague.cfss.domain.enums.OrderHandleType;
import club.coderleague.cfss.util.CommonUtil;
import club.coderleague.data.jpa.domain.Page;

/**
 * 订单服务。
 * @author Chrise
 */
@Service
public class OrderService {
	@Autowired
	private GoodDao goodDao;
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private OrderGoodDao ogDao;
	@Autowired
	private OrderLogDao olDao;
	@Autowired
	private FileUploadSettings fuSettings;
	
	/**
	 * 保存订单。
	 * @author Chrise 2021年1月28日
	 * @param request 订单请求。
	 * @param session 用户会话。
	 * @return 错误消息。
	 */
	public String saveOrder(SubmitOrderRequest request, UserSession session) {
		List<OrderGoodRequest> ogrs = request.getOrdergoods();
		
		List<Long> goodids = new ArrayList<Long>();
		Map<Long, OrderGoodRequest> goodmap = new HashMap<Long, OrderGoodRequest>();
		for (OrderGoodRequest ogr : ogrs) {
			goodids.add(ogr.getGoodid());
			goodmap.put(ogr.getGoodid(), ogr);
		}
		
		List<OrderGoodCheck> goods = this.goodDao.checkOrderGoods(goodids);
		if (goods.size() != ogrs.size()) return "商品信息有变化，请刷新确认！";
		
		for (OrderGoodCheck good : goods) {
			OrderGoodRequest ogr = goodmap.get(good.getGoodid());
			if (good.getGoodprice() != ogr.getGoodprice().doubleValue()) {
				return "商品信息有变化，请刷新确认！";
			}
		}
		
		Date date = new Date();
		
		Orders order = null;
		long supplierid = 0L;
		double ordertotal = 0.0;
		for (OrderGoodCheck good : goods) {
			if (good.getSupplierid() != supplierid) {
				if (order != null) {
					order.setOrdertotal(ordertotal);
					ordertotal = 0.0;
				}
				
				supplierid = good.getSupplierid();
				order = new Orders(EntityState.CONFIRMED.getValue(), supplierid, session.getOrgid(), 0.0, date, null, null, null, null);
				this.orderDao.save(order);
				
				Orderlogs orderlog = new Orderlogs(EntityState.VALID.getValue(), order.getEntityid(), session.getId(), OrderHandleType.ORDER.getValue(), date);
				this.olDao.save(orderlog);
			}
			
			Integer goodnumber = goodmap.get(good.getGoodid()).getGoodnumber();
			double goodtotal = good.getGoodprice() * goodnumber;
			ordertotal += goodtotal;
			
			Ordergoods ordergood = new Ordergoods(EntityState.VALID.getValue(), order.getEntityid(), good.getGoodid(), 
				good.getGoodname(), good.getGoodspecs(), good.getMeteringunit(), good.getGoodprice(), goodnumber, goodtotal);
			this.ogDao.save(ordergood);
		}
		if (order != null) order.setOrdertotal(ordertotal);
		
		return null;
	}
	
	/**
	 * 加载订单数据。
	 * @author Chrise 2021年1月31日
	 * @param entId 企业标识。
	 * @param orderState 订单状态。
	 * @param isSupplier 是否是供应商。
	 * @return 订单数据。
	 */
	public Map<String, Object> loadOrderData(long entId, Integer orderState, boolean isSupplier) {
		List<Order> orders = this.orderDao.queryOrderList(entId, orderState, isSupplier);
		for (Order order : orders) {
			order.setOrdergoods(this.ogDao.queryGoodCovers(order.getOrderid(), this.fuSettings.getRootVirtual() + this.fuSettings.getGoodpicturePath()));
		}
		
		int handlingNumber = this.orderDao.queryHandlingNumber(entId, isSupplier);
		
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("orders", orders);
		result.put("handlingNumber", handlingNumber);
		return result;
	}
	
	/**
	 * 确认发货。
	 * @author Chrise 2021年2月1日
	 * @param orderid 订单标识。
	 * @param session 用户会话。
	 * @return 错误消息。
	 */
	public String execConfirmDistribute(long orderid, UserSession session) {
		Orders order = this.orderDao.getOne(orderid);
		if (!EntityState.CONFIRMED.equalsValue(order.getEntitystate())) return "订单状态异常！";
		
		Date date = new Date();
		
		order.setEntitystate(EntityState.DISTRIBUTED.getValue());
		order.setDistributetime(date);
		
		Orderlogs log = new Orderlogs(EntityState.VALID.getValue(), orderid, session.getId(), OrderHandleType.DISTRIBUTE.getValue(), date);
		this.olDao.save(log);
		
		return null;
	}
	
	/**
	 * 取消订单。
	 * @author Chrise 2021年2月2日
	 * @param orderid 订单标识。
	 * @param session 用户会话。
	 * @param isSupplier 是否是供应商。
	 * @return 错误消息。
	 */
	public String execCancelOrder(long orderid, UserSession session, boolean isSupplier) {
		Orders order = this.orderDao.getOne(orderid);
		if (isSupplier) {
			if (!EntityState.DISTRIBUTED.equalsValue(order.getEntitystate())) return "订单状态异常！";
		} else {
			if (!EntityState.CONFIRMED.equalsValue(order.getEntitystate())) return "订单状态异常！";
		}
		
		Date date = new Date();
		
		order.setEntitystate(EntityState.CANCELLED.getValue());
		order.setCanceltime(date);
		
		Orderlogs log = new Orderlogs(EntityState.VALID.getValue(), orderid, session.getId(), OrderHandleType.CANCEL.getValue(), date);
		this.olDao.save(log);
		
		return null;
	}
	
	/**
	 * 确认收货。
	 * @author Chrise 2021年2月2日
	 * @param orderid 订单标识。
	 * @param session 用户会话。
	 * @return 错误消息。
	 */
	public String execConfirmReceive(long orderid, UserSession session) {
		Orders order = this.orderDao.getOne(orderid);
		if (!EntityState.DISTRIBUTED.equalsValue(order.getEntitystate())) return "订单状态异常！";
		
		Date date = new Date();
		
		order.setEntitystate(EntityState.COMPLETED.getValue());
		order.setCompletetime(date);
		
		Orderlogs log = new Orderlogs(EntityState.VALID.getValue(), orderid, session.getId(), OrderHandleType.RECEIVE.getValue(), date);
		this.olDao.save(log);
		
		return null;
	}
	
	/**
	 * 加载订单详情数据。
	 * @author Chrise 2021年2月4日
	 * @param orderid 订单标识。
	 * @param isSupplier 是否是供应商。
	 * @return 订单详情数据。
	 */
	public Order loadOrderDetailData(long orderid, boolean isSupplier) {
		Order order = this.orderDao.queryOrderDetail(orderid, isSupplier);
		order.setOrdergoods(this.ogDao.queryGoodDetails(order.getOrderid(), this.fuSettings.getRootVirtual() + this.fuSettings.getGoodpicturePath()));
		return order;
	}
	
	/**
	 * 加载订单分页数据。
	 * @author Chrise 2021年2月6日
	 * @param states 状态。
	 * @param keyword 关键字。
	 * @param pageIndex 分页索引。
	 * @param pageSize 分页大小。
	 * @return 订单分页数据。
	 */
	public Page<Map<String, Object>> loadListData(String states, String keyword, Integer pageIndex, Integer pageSize) {
		List<Integer> list = new ArrayList<Integer>();
		if (CommonUtil.isEmpty(states)) {
			list.add(EntityState.COMPLETED.getValue());
		} else {
			String[] array = states.split(",");
			for (String s : array) {
				list.add(Integer.valueOf(s));
			}
		}
		
		return this.orderDao.queryListData(list, keyword, pageIndex, pageSize);
	}
	
	/**
	 * 加载订单商品分页数据。
	 * @author Chrise 2021年2月6日
	 * @param orderid 订单标识。
	 * @param pageIndex 分页索引。
	 * @param pageSize 分页大小。
	 * @return 订单商品分页数据。
	 */
	public Page<Map<String, Object>> loadGoodListData(Long orderid, Integer pageIndex, Integer pageSize) {
		return this.ogDao.queryGoodListData(orderid, pageIndex, pageSize);
	}
}
